Vector, Matrix, Array


In [2]:
a = [1; 2; 3]


Out[2]:
3-element Array{Int64,1}:
 1
 2
 3

In [3]:
println(a)


[1, 2, 3]

In [4]:
a = [1, 2, 3]


Out[4]:
3-element Array{Int64,1}:
 1
 2
 3

In [5]:
a = [1 2 3]


Out[5]:
1×3 Array{Int64,2}:
 1  2  3

In [6]:
b = [4 5 6]


Out[6]:
1×3 Array{Int64,2}:
 4  5  6

In [7]:
A = [1 2 3; 4 5 6]


Out[7]:
2×3 Array{Int64,2}:
 1  2  3
 4  5  6
  • 세미콜론이 새로운 row를 의미함

In [8]:
A[1,3]


Out[8]:
3
  • Julia는 index 시작시 1부터 시작함

In [9]:
A[1]


Out[9]:
1

In [10]:
A[1,1]


Out[10]:
1

In [11]:
A[1,2]


Out[11]:
2

In [12]:
A[2,1]


Out[12]:
4
  • transpose() 또는 '를 사용할 수 이씀

In [13]:
transpose(A)


Out[13]:
3×2 LinearAlgebra.Transpose{Int64,Array{Int64,2}}:
 1  4
 2  5
 3  6

In [14]:
A'


Out[14]:
3×2 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}:
 1  4
 2  5
 3  6
  • inner product, dot product
    • 그냥 곱하는 방법
    • LinearAlgebra의 dot을 사용하는 방법

In [15]:
a = [1; 2; 3;]
c = [7; 8; 9;]


Out[15]:
3-element Array{Int64,1}:
 7
 8
 9

In [16]:
a'*c


Out[16]:
50
  • using이 python의 import랑 비슷한 느낌

In [17]:
using LinearAlgebra

In [18]:
dot(a, c)


Out[18]:
50

In [19]:
Matrix(1.0I, 2, 2)
# I는 identity matrix => 단위 행렬. I가 없으면 에러남


Out[19]:
2×2 Array{Float64,2}:
 1.0  0.0
 0.0  1.0

In [20]:
Matrix(1.0, 2, 2)


MethodError: no method matching Array{T,2} where T(::Float64, ::Int64, ::Int64)
Closest candidates are:
  Array{T,2} where T(!Matched::UndefInitializer, ::Integer, ::Integer) at sysimg.jl:152
  Array{T,2} where T(!Matched::UniformScaling, ::Integer, ::Integer) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/uniformscaling.jl:341

Stacktrace:
 [1] top-level scope at In[20]:1
  • zero matrix는 zeros() 사용

In [21]:
zeros(4,1)


Out[21]:
4×1 Array{Float64,2}:
 0.0
 0.0
 0.0
 0.0

In [22]:
zeros(2,3)


Out[22]:
2×3 Array{Float64,2}:
 0.0  0.0  0.0
 0.0  0.0  0.0

In [23]:
ones(1,3)


Out[23]:
1×3 Array{Float64,2}:
 1.0  1.0  1.0

In [24]:
ones(2,3)


Out[24]:
2×3 Array{Float64,2}:
 1.0  1.0  1.0
 1.0  1.0  1.0
  • inv() : Inverse

In [25]:
B = [1 3 2; 3 2 2; 1 1 1]


Out[25]:
3×3 Array{Int64,2}:
 1  3  2
 3  2  2
 1  1  1

In [26]:
inv(B)


Out[26]:
3×3 Array{Float64,2}:
  1.11022e-16   1.0  -2.0
  1.0           1.0  -4.0
 -1.0          -2.0   7.0

In [27]:
B * inv(B)


Out[27]:
3×3 Array{Float64,2}:
  1.0          0.0  0.0
  0.0          1.0  0.0
 -2.22045e-16  0.0  1.0
  • 0이 아니라 -2.22045e-16라고 나온건 inverse matrix의 연산이 정확하지 않아서 그럼

In [28]:
inv(B)[2,1]


Out[28]:
1.0000000000000004

In [29]:
a = [1; 2; 3]


Out[29]:
3-element Array{Int64,1}:
 1
 2
 3

In [30]:
b = [1.0; 2; 3]


Out[30]:
3-element Array{Float64,1}:
 1.0
 2.0
 3.0
  • a는 Int64, b는 Float64
  • Array object 특정 타입으로 만들고 싶은 경우

In [31]:
d = Array{Float64}(undef, 3)


Out[31]:
3-element Array{Float64,1}:
 2.3064115165e-314
 2.3064115323e-314
 2.3091702605e-314

In [32]:
d[1] = 1


Out[32]:
1

In [33]:
d[2] = 2


Out[33]:
2

In [34]:
d[3] = 3


Out[34]:
3

In [35]:
d


Out[35]:
3-element Array{Float64,1}:
 1.0
 2.0
 3.0

Tuple

  • a pair of data types

In [36]:
pairs = Array{Tuple{Int64, Int64}}(undef, 3)


Out[36]:
3-element Array{Tuple{Int64,Int64},1}:
 (4671453744, 4671453888)
 (4671453936, 4671453984)
 (4671454032, 4678541088)

In [37]:
pairs


Out[37]:
3-element Array{Tuple{Int64,Int64},1}:
 (4671453744, 4671453888)
 (4671453936, 4671453984)
 (4671454032, 4678541088)

In [38]:
pairs2 = (1, 3)


Out[38]:
(1, 3)

In [39]:
pairs[1]


Out[39]:
(4671453744, 4671453888)

In [40]:
pairs[1] = (1,2)


Out[40]:
(1, 2)

In [41]:
pairs[2] = (2,3)
pairs[3] = (3,4)


Out[41]:
(3, 4)

In [42]:
pairs


Out[42]:
3-element Array{Tuple{Int64,Int64},1}:
 (1, 2)
 (2, 3)
 (3, 4)

In [43]:
# 이거랑 동일함
pairs = [(1,2); (2,3); (3,4)]


Out[43]:
3-element Array{Tuple{Int64,Int64},1}:
 (1, 2)
 (2, 3)
 (3, 4)
  • Tuple은 노드와 링크로 이루어진 network data를 핸들링할 때 유용

In [44]:
ijk_array = Array{Tuple{Int64, Int64, Int64}}(undef, 3)


Out[44]:
3-element Array{Tuple{Int64,Int64,Int64},1}:
 (4662978080, 4669435552, 4669435392)
 (1, 4669435632, 4669435712)         
 (4669435792, 4, 4)                  

In [45]:
ijk_array[1] = (1, 4, 2)


Out[45]:
(1, 4, 2)

Indices and Ranges


In [46]:
a = [10; 20; 30; 40; 50; 60; 70; 80; 90]


Out[46]:
9-element Array{Int64,1}:
 10
 20
 30
 40
 50
 60
 70
 80
 90

In [47]:
# range
a[1:3]


Out[47]:
3-element Array{Int64,1}:
 10
 20
 30

In [48]:
# 1부터 9까지 중 +3
a[1:3:9]


Out[48]:
3-element Array{Int64,1}:
 10
 40
 70

In [49]:
a[3]


Out[49]:
30

In [50]:
a[2:3:7]


Out[50]:
2-element Array{Int64,1}:
 20
 50
  • end라는 키워드도 있음

In [51]:
a[end-2:end]


Out[51]:
3-element Array{Int64,1}:
 70
 80
 90

In [52]:
b = [200; 300; 400]


Out[52]:
3-element Array{Int64,1}:
 200
 300
 400

In [53]:
a[2:4] = b


Out[53]:
3-element Array{Int64,1}:
 200
 300
 400

In [54]:
a


Out[54]:
9-element Array{Int64,1}:
  10
 200
 300
 400
  50
  60
  70
  80
  90
  • collect를 사용해도 됨

In [55]:
c = collect(1:2:9)


Out[55]:
5-element Array{Int64,1}:
 1
 3
 5
 7
 9

Printing Messages

  • println과 print 존재

In [56]:
println("Hello World")


Hello World

In [57]:
print("hello "); print("world"); print(" Again")


hello world Again

In [58]:
println("hello "); println("world"); println(" Again")


hello 
world
 Again

In [59]:
a = 123.0


Out[59]:
123.0
  • Python f-string과 유사한 기능은 $변수 로 사용 가능. 혹은 $(연산)

In [60]:
println("The value of a = ", a)


The value of a = 123.0

In [61]:
println("a is $a, and a-10 is $(a-10).")


a is 123.0, and a-10 is 113.0.

In [62]:
b = [1; 3; 10]


Out[62]:
3-element Array{Int64,1}:
  1
  3
 10

In [63]:
println("b is $b")


b is [1, 3, 10]

In [64]:
println("the second element of b is $(b[2])")


the second element of b is 3
  • Printf라는걸 하면.. python의 string.format(a=a) 이런게 가능한듯
    • indeger는 %d

In [65]:
using Printf

In [66]:
@printf("The %s of a = %f", "value", a)


The value of a = 123.000000

In [67]:
c = [123.12345; 10.983; 1.092312]


Out[67]:
3-element Array{Float64,1}:
 123.12345 
  10.983   
   1.092312
  • for문은 end를 꼭 붙여야하고, : <- 이런게 없음

In [68]:
for i in 1:length(c)
    @printf("c[%d] = %7.2f\n", i, c[i])
end


c[1] =  123.12
c[2] =   10.98
c[3] =    1.09
  • %7.2f는 토탈 넘버는 7이고 소수점은 2자리까지
  • @sprintf도 있음 => 다만 리턴이 string(screen 표시 대신)

In [69]:
str = @sprintf("The %s of a = %f", "value", a)


Out[69]:
"The value of a = 123.000000"

In [70]:
println(str)


The value of a = 123.000000

Collection, Dictionary, For-Loop


In [71]:
for i in 1:5
    println("This is number $i")
end


This is number 1
This is number 2
This is number 3
This is number 4
This is number 5
  • 구조
for i in I
    #do something here for each i
end
  • 참고로 I는 collection(보통 Range 또는 Dict)

In [72]:
for i in 1:5
    if i >= 3
        break
    end
    println("This is number $i")
end


This is number 1
This is number 2

In [73]:
my_keys = ["hi", "bye", "cool"]
my_values = ["football", "pocketmon","swim"]


Out[73]:
3-element Array{String,1}:
 "football" 
 "pocketmon"
 "swim"     

In [74]:
d = Dict()

for i in 1:length(my_keys)
    d[my_keys[i]] = my_values[i]
end

In [75]:
d


Out[75]:
Dict{Any,Any} with 3 entries:
  "bye"  => "pocketmon"
  "hi"   => "football"
  "cool" => "swim"

In [76]:
for (key, value) in d
    println("$key is a $value player")
end


bye is a pocketmon player
hi is a football player
cool is a swim player

In [77]:
d["Diego Maradona"] = "football"


Out[77]:
"football"
  • '이 아니라 "을 써야함
  • network

In [78]:
links = [(1,2), (3,4), (4,2)]


Out[78]:
3-element Array{Tuple{Int64,Int64},1}:
 (1, 2)
 (3, 4)
 (4, 2)

In [79]:
link_costs = [5, 13, 8]


Out[79]:
3-element Array{Int64,1}:
  5
 13
  8

In [80]:
link_dict = Dict()


Out[80]:
Dict{Any,Any} with 0 entries

In [81]:
for i in 1:length(links)
    link_dict[links[i]] = link_costs[i]
end

In [82]:
link_dict


Out[82]:
Dict{Any,Any} with 3 entries:
  (1, 2) => 5
  (4, 2) => 8
  (3, 4) => 13

In [83]:
for (link, cost) in link_dict
    println("Link $link has cost of $cost")
end


Link (1, 2) has cost of 5
Link (4, 2) has cost of 8
Link (3, 4) has cost of 13

Function


In [84]:
function f(x,y)
    return 3x+y
end


Out[84]:
f (generic function with 1 method)

In [85]:
f(1,3)


Out[85]:
6

In [86]:
3*(f(3,2)+f(5,6))


Out[86]:
96

In [87]:
function my_func(n, m)
    a = zeros(n, 1)
    b = ones(m, 1)
    return a,b
end


Out[87]:
my_func (generic function with 1 method)

In [88]:
x, y = my_func(3,2)


Out[88]:
([0.0; 0.0; 0.0], [1.0; 1.0])

In [89]:
x


Out[89]:
3×1 Array{Float64,2}:
 0.0
 0.0
 0.0

In [90]:
y


Out[90]:
2×1 Array{Float64,2}:
 1.0
 1.0

In [91]:
sqrt(9)


Out[91]:
3.0

In [92]:
sqrt([9 16])


DimensionMismatch("matrix is not square: dimensions are (1, 2)")

Stacktrace:
 [1] sqrt(::Array{Int64,2}) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/LinearAlgebra.jl:214
 [2] top-level scope at In[92]:1

In [93]:
sqrt.([9 16])


Out[93]:
1×2 Array{Float64,2}:
 3.0  4.0
  • 그냥 sqrt => 단일에 적용
  • sqrt. => each element에 적용(map이라고 보면 되려나)
  • 모든 함수에 적용

In [94]:
myfunc(x) = sin(x) + 3*x


Out[94]:
myfunc (generic function with 1 method)

In [95]:
myfunc(3)


Out[95]:
9.141120008059866

In [96]:
myfunc([5 10])


DimensionMismatch("matrix is not square: dimensions are (1, 2)")

Stacktrace:
 [1] exp!(::Array{Complex{Float64},2}) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/LinearAlgebra.jl:214
 [2] sin(::Array{Int64,2}) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.1/LinearAlgebra/src/dense.jl:792
 [3] myfunc(::Array{Int64,2}) at ./In[94]:1
 [4] top-level scope at In[96]:1

In [97]:
myfunc.([5 10])


Out[97]:
1×2 Array{Float64,2}:
 14.0411  29.456

Scope of Variables


In [98]:
function f(x)
    retun x+2
end


syntax: extra token "x" after end of expression

In [99]:
function g(x)
    return 3x+3
end


Out[99]:
g (generic function with 1 method)
  • 여기 인자가 둘다 x를 줬는데, 다른 scope block으로 정의되서 충돌하지 않음

In [100]:
function f(x)
    return x+z
end

function run()
    z=10
    return f(5)
end


Out[100]:
run (generic function with 1 method)

In [101]:
run()


UndefVarError: z not defined

Stacktrace:
 [1] f(::Int64) at ./In[100]:2
 [2] run() at ./In[100]:7
 [3] top-level scope at In[101]:1
  • z가 안됨. 리팩토링

In [102]:
function f(x)
    return x+a
end

function run()
    return f(5) 
end

a=10
run()


Out[102]:
15

In [103]:
function f2(x)
    a=0
    return x+a
end

a=5


Out[103]:
5

In [104]:
println(f2(1))


1

In [105]:
println(a)


5
  • 변수 앞에 _를 붙이면 local variable

In [106]:
function f3(x)
    _a = 0
    return x + _a
end


Out[106]:
f3 (generic function with 1 method)

In [107]:
a = 5
println(f3(1))
println(a)


1
5

In [108]:
function f4(x, a)
    return x+a
end

a = 5
println(f4(1, a))
println(a)


6
5

In [109]:
a = [1 2 3 4 5]
s = 0
for i in 1:length(A)
    s += a[i]
end


BoundsError: attempt to access 1×5 Array{Int64,2} at index [6]

Stacktrace:
 [1] getindex(::Array{Int64,2}, ::Int64) at ./array.jl:729
 [2] top-level scope at ./In[109]:4

In [110]:
function my_sum(a)
    s = 0
    for i in 1:5
        s += a[i]
    end
    return s
end

a = [1; 2; 3; 4; 5]


Out[110]:
5-element Array{Int64,1}:
 1
 2
 3
 4
 5

In [111]:
my_sum(a)


Out[111]:
15

Random Number Generation


In [112]:
rand()


Out[112]:
0.9266495281538778

In [113]:
rand()


Out[113]:
0.8304477728220296

In [114]:
rand(5)


Out[114]:
5-element Array{Float64,1}:
 0.8324770166728122
 0.2662287032474082
 0.6933367170942821
 0.2955082361684169
 0.577475034743496 
  • index 선택

In [115]:
rand() * 100


Out[115]:
93.7998436597625

In [116]:
rand(1:10)


Out[116]:
4
  • randn : 정규분포

In [117]:
randn(5)


Out[117]:
5-element Array{Float64,1}:
 -1.2142547850901897 
 -1.991431544403744  
 -1.3196835160607816 
  1.1693537449632032 
  0.28594133262787147

In [118]:
function my_randn(n, mu, sigma)
    return randn(n) .* sigma .+mu
end


Out[118]:
my_randn (generic function with 1 method)

In [119]:
my_randn(10, 50, 3)


Out[119]:
10-element Array{Float64,1}:
 48.96424536283605 
 45.82637579794923 
 52.22822347403981 
 49.35333388905027 
 48.71153119242729 
 52.760595462606034
 46.632272155091094
 52.03787969109315 
 53.18965634376912 
 55.264539739277296

In [120]:
using Pkg

In [121]:
Pkg.add("StatsFuns")


  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
 Resolving package versions...
  Updating `~/.julia/environments/v1.1/Project.toml`
 [no changes]
  Updating `~/.julia/environments/v1.1/Manifest.toml`
 [no changes]

In [122]:
Pkg.build("StatsFuns")


  Building SpecialFunctions → `~/.julia/packages/SpecialFunctions/ne2iw/deps/build.log`
  Building Rmath ───────────→ `~/.julia/packages/Rmath/BoBag/deps/build.log`

In [123]:
using StatsFuns


┌ Info: Precompiling StatsFuns [4c63d2b9-4356-54db-8cca-17b64c39e42c]
└ @ Base loading.jl:1186
ERROR: LoadError: SystemError: opening file "/Users/byeon/.julia/compiled/v1.1/SpecialFunctions/78gOt.ji": Permission denied
Stacktrace:
 [1] #systemerror#43(::Nothing, ::Function, ::String, ::Bool) at ./error.jl:134
 [2] systemerror at ./error.jl:134 [inlined]
 [3] #open#309(::Bool, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Function, ::String) at ./iostream.jl:289
 [4] #open at ./none:0 [inlined]
 [5] open(::String, ::String) at ./iostream.jl:345
 [6] stale_cachefile(::String, ::String) at ./loading.jl:1321
 [7] _require_search_from_serialized(::Base.PkgId, ::String) at ./loading.jl:693
 [8] _require(::Base.PkgId) at ./loading.jl:937
 [9] require(::Base.PkgId) at ./loading.jl:858
 [10] require(::Module, ::Symbol) at ./loading.jl:853
 [11] include at ./boot.jl:326 [inlined]
 [12] include_relative(::Module, ::String) at ./loading.jl:1038
 [13] include(::Module, ::String) at ./sysimg.jl:29
 [14] top-level scope at none:2
 [15] eval at ./boot.jl:328 [inlined]
 [16] eval(::Expr) at ./client.jl:404
 [17] top-level scope at ./none:3
in expression starting at /Users/byeon/.julia/packages/StatsFuns/f6KKB/src/StatsFuns.jl:6
Failed to precompile StatsFuns [4c63d2b9-4356-54db-8cca-17b64c39e42c] to /Users/byeon/.julia/compiled/v1.1/StatsFuns/530lR.ji.

Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] compilecache(::Base.PkgId, ::String) at ./loading.jl:1197
 [3] _require(::Base.PkgId) at ./loading.jl:960
 [4] require(::Base.PkgId) at ./loading.jl:858
 [5] require(::Module, ::Symbol) at ./loading.jl:853
 [6] top-level scope at In[123]:1

In [124]:
mu = 50; sigma = 3;

In [125]:
normpdf(mu, sigma, 52)


UndefVarError: normpdf not defined

Stacktrace:
 [1] top-level scope at In[125]:1
  • 흠 에러가 난당

File input/output


In [127]:
data_file_path = "data.txt"


Out[127]:
"data.txt"

In [128]:
data_file = open(data_file_path)


Out[128]:
IOStream(<file data.txt>)

In [129]:
data = readlines(data_file)


Out[129]:
3-element Array{String,1}:
 "This is the first line"
 "this is the second"    
 "thie is the third"     

In [130]:
close(data_file)

In [131]:
for line in data
    println(line)
end


This is the first line
this is the second
thie is the third

In [132]:
output_file_path = "results1.txt"
output_file = open(output_file_path, "w")
print(output_file, "Magic Johnson")
println(output_file, "is a basketball player")
println(output_file, "Michael jordan is also a basketball palyer")
close(output_file)
  • 오 print찍으면 저장할 수 있네
  • open시 a 옵션을 주면 append 가능

CSV


In [134]:
using DelimitedFiles

In [136]:
csv_file_name = "data.csv"
csv_data = readdlm(csv_file_name, ',', header=true)


Out[136]:
(Any[1 2 2 ""; 1 3 4.5 ""; … ; 2 4 3 ""; 3 4 5 ""], AbstractString["start node" " end node link length" "" ""])

In [138]:
data = csv_data[1]
header = csv_data[2]


Out[138]:
1×4 Array{AbstractString,2}:
 "start node"  " end node link length"  ""  ""

In [139]:
header


Out[139]:
1×4 Array{AbstractString,2}:
 "start node"  " end node link length"  ""  ""

In [140]:
data


Out[140]:
5×4 Array{Any,2}:
 1  2  2    ""
 1  3  4.5  ""
 2  3  6    ""
 2  4  3    ""
 3  4  5    ""

In [141]:
start_node = round.(Int, data[:,1])


Out[141]:
5-element Array{Int64,1}:
 1
 1
 2
 2
 3

In [145]:
end_node = round.(Int, data[:, 2])


Out[145]:
5-element Array{Int64,1}:
 2
 3
 3
 4
 4

In [146]:
link_length = data[:, 3]


Out[146]:
5-element Array{Any,1}:
 2  
 4.5
 6  
 3  
 5  

Plotting


In [147]:
using PyPlot


┌ Info: Recompiling stale cache file /Users/byeon/.julia/compiled/v1.1/PyPlot/oatAj.ji for PyPlot [d330b81b-6aea-500a-939a-2ce795aea3ee]
└ @ Base loading.jl:1184

In [148]:
# Preparing a figure object
fig = figure()

# Data
x = range(0, stop=2*pi, length=1000)
y = sin.(3*x)

# Plotting with linewidth and linestyle specified
plot(x, y, color="blue", linewidth=2.0, linestyle="--")

# Labeling the axes
xlabel(L"value of $x$")
ylabel(L"\sin(3x)")

# Title
title("Test plotting")

# Save the figure as PNG and PDF
savefig("plot1.png")
savefig("plot1.pdf")

# Close the figure object
close(fig)

In [149]:
lower_bound = [4.0, 4.2, 4.4, 4.8, 4.9, 4.95, 4.99, 5.00]
upper_bound = [5.4, 5.3, 5.3, 5.2, 5.2, 5.15, 5.10, 5.05]
iter = 1:8

# Creating a new figure object
fig = figure()

# Plotting two datasets
plot(iter, lower_bound, color="red", linewidth=2.0, linestyle="-",
 marker="o", label=L"Lower Bound $Z^k_L$")
plot(iter, upper_bound, color="blue", linewidth=2.0, linestyle="-.",
 marker="D", label=L"Upper Bound $Z^k_U$")

# Labeling axes
xlabel(L"iteration clock $k$", fontsize="xx-large")
ylabel("objective function value", fontsize="xx-large")

# Putting the legend and determining the location
legend(loc="upper right", fontsize="x-large")

# Add grid lines
grid(color="#DDDDDD", linestyle="-", linewidth=1.0)
tick_params(axis="both", which="major", labelsize="x-large")

# Title
title("Lower and Upper Bounds")

# Save the figure as PNG and PDF
savefig("plot2.png")
savefig("plot2.pdf")

# Closing the figure object
close(fig)

In [150]:
# Data
data = randn(100) # Some Random Data
nbins = 10        # Number of bins

# Creating a new figure object
fig = figure()

# Histogram
plt[:hist](data, nbins)

# Title
title("Histogram")

# Save the figure as PNG and PDF
savefig("plot3.png")
savefig("plot3.pdf")

# Closing the figure object
close(fig)


┌ Warning: `getindex(o::PyObject, s::Symbol)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o.s` instead of `o[:s]`.
│   caller = top-level scope at In[150]:7
└ @ Core In[150]:7

In [ ]: